package com.valuegroup.smarttodo.data.service;

import android.text.TextUtils;

import com.valuegroup.smarttodo.data.ServiceFactory;
import com.valuegroup.smarttodo.data.model.AppStatus;
import com.valuegroup.smarttodo.data.model.Curriculum;
import com.valuegroup.smarttodo.data.model.CurriculumDao;
import com.valuegroup.smarttodo.data.model.Event;
import com.valuegroup.smarttodo.data.model.EventDao;
import com.valuegroup.smarttodo.data.vo.CurriculumEventVo;
import com.valuegroup.smarttodo.data.vo.CurriculumItemVo;
import com.valuegroup.smarttodo.plugins.pickdialog.DateUtils;

import org.greenrobot.greendao.query.QueryBuilder;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class CurriculumService extends BaseService {


    public List<CurriculumItemVo> findCurriculumForHome(boolean hideFinish) {
        List<CurriculumItemVo> result = new ArrayList<>();

        List<Curriculum> data = getCurriculumDao().queryBuilder().orderAsc(CurriculumDao.Properties.Id).list();

        for (Curriculum t : data) {
            CurriculumItemVo vo = convertCurriculumItemVo(t);
            if (hideFinish) {
                if (vo != null && !vo.isShowFinish()) {
                    result.add(vo);
                }
            } else {
                result.add(vo);
            }
        }
        return result;
    }

    public List<CurriculumEventVo> findCurriculumEventForHome(Long id) {
        List<CurriculumEventVo> result = new ArrayList<>();

        List<Event> data = findCurriculumEvent(id);
        for (Event e : data) {
            CurriculumEventVo v = new CurriculumEventVo();
            v.setId(e.getId());
            if (e.getJoinSchedule() && e.getScheduleDt() != null) {
                v.setScheduDt(DateUtils.date2str(e.getScheduleDt(), DateUtils.F31));
            }
            v.setMinute(e.getPreMinute());
            v.setTitle(e.getTitle());
            v.setFinish(e.getFinish());
            result.add(v);
        }
        return result;

    }

    public CurriculumItemVo getCurriculumItemVo(long id) {
        return convertCurriculumItemVo(getCurriculumDao().load(id));
    }


    private List<Event> findCurriculumEvent(Long id) {
        if (id == null) {
            return new ArrayList<>();
        }

        return getEventDao().queryBuilder()
                .where(EventDao.Properties.SourceId.eq(id))
                .where(EventDao.Properties.EventType.eq(AppStatus.EventType.STUDY))
                .where(EventDao.Properties.Status.eq(AppStatus.Status.NORMAL))
                .orderAsc(EventDao.Properties.Id)
                .list();
    }

    public int[] countCurriculumEvent(Long id) {
        int[] result = new int[2];
        result[0] = countCurriculumEvent(id, false);
        result[1] = countCurriculumEvent(id, true);
        return result;
    }

    private int countCurriculumEvent(Long id, boolean onlyFinish) {
        if (id == null) {
            return 0;
        }
        QueryBuilder<Event> q = getEventDao().queryBuilder();
        q.where(EventDao.Properties.SourceId.eq(id));
        q.where(EventDao.Properties.EventType.eq(AppStatus.EventType.STUDY));
        q.where(EventDao.Properties.Status.eq(AppStatus.Status.NORMAL));
        if (onlyFinish) {
            q.where(EventDao.Properties.Finish.eq(true));
        }
        return (int) q.count();
    }

    public Curriculum getDefaultCurriculum() {
        Curriculum t = new Curriculum();
        Date today = new Date();
        t.setTitle("新课程");
        t.setStartDt(today);
        t.setEndDt(DateUtils.moveDay(today, 15));
        t.setRemindTime(null);
        t.setOpenAuto(true);
        t.setDayTargetMinute(25);
        t.setStudyFinish(false);
        t.setFinishDt(null);
        t.setImagePath(null);
        t.setIsPastDue(false);
        t.setSort(1);
        t.setCreatedDt(today);
        t.setUpdatedDt(today);
        t.setStatus(AppStatus.Status.NORMAL);
        return t;
    }

    public Event getDefaultEvent(Long pid) {
        Event t = new Event();
        t.setTitle("学习事件");
        t.setSourceId(pid);
        t.setEventType(AppStatus.EventType.STUDY);
        t.setPreMinute(25);
        t.setJoinSchedule(false);
        t.setJoinScheduleDt(null);
        t.setScheduleWeekNum(null);
        t.setScheduleDt(null);
        t.setFinish(false);
        t.setFinishDt(null);
        t.setAutoContinue(false);
        t.setCreatedDt(new Date());
        t.setUpdatedDt(t.getCreatedDt());
        t.setStatus(AppStatus.Status.NORMAL);
        return t;
    }


    private CurriculumItemVo convertCurriculumItemVo(Curriculum t) {
        CurriculumItemVo v = new CurriculumItemVo();

        int finish = 0;

        List<Event> steps = findCurriculumEvent(t.getId());
        for (Event s : steps) {
            if (s.getFinish()) {
                finish++;
            }
        }

        float progress = (float) finish / steps.size() * 100;

        v.setId(t.getId());
        v.setLabTitle(t.getTitle());
        v.setLabDate(t.getEndDt());
        v.setImgCover(t.getImagePath());
        v.setBranchTotal(steps.size());
        v.setBranchFinish(finish);
        v.setLabProgress(progress);
        v.setSort(t.getSort());
        v.setShowFinish(t.getStudyFinish());
        v.setShowAuto(t.getOpenAuto());

        return v;
    }

    public void doFinish(Long id, boolean b) {
        if (id == null) {
            return;
        }

        Curriculum t = getCurriculumDao().load(id);
        if (t != null && t.getStudyFinish() != b) {

            t.setStudyFinish(b);
            t.setFinishDt(b ? new Date() : null);
            t.setUpdatedDt(new Date());

            // 完成时间超过截止日期标记逾期状态
            if (b && DateUtils.compareDate(t.getEndDt(), t.getFinishDt()) < 0) {
                t.setIsPastDue(true);
            }

            getCurriculumDao().save(t);
        }
    }


    public CurriculumEventVo saveCurriculumEvent(CurriculumEventVo vo) {
        if (vo.getPid() == null) {
            return null;
        }
        Curriculum t = getCurriculumDao().load(vo.getPid());
        if (t == null) {
            return null;
        }

        Event e = getDefaultEvent(vo.getPid());
        e.setTitle(vo.getTitle());
        if (vo.getMinute() != 0) {
            e.setPreMinute(vo.getMinute());
        }
        // 自动续学,所属事务需要特殊标记(标记了自动续学的未排期事务不在事件排期列表中展示)
        if (t.getOpenAuto()) {
            e.setAutoContinue(true);
        }

        getEventDao().save(e);
        vo.setId(e.getId());
        return vo;
    }

    public Curriculum saveImgCover(Long id, String uri) {
        Curriculum t = getCurriculumDao().load(id);
        if (t == null || TextUtils.isEmpty(uri)) {
            return null;
        }

        t.setImagePath(uri);
        t.setUpdatedDt(new Date());
        getCurriculumDao().save(t);
        return t;
    }


    public void resetCurriculum(Long id) {
        if (id == null) {
            return;
        }
        Curriculum t = getCurriculumDao().load(id);
        if (t == null) {
            return;
        }

        // 清空学习事件
        List<Event> events = findCurriculumEvent(id);
        for (Event e : events) {
            // 删除关联的任务
            ServiceFactory.getInstance().getEventService().delEventTask(e);
            // 删除事件
            getEventDao().delete(e);
        }

        // 课程
        t.setStartDt(new Date());
        t.setEndDt(DateUtils.moveDay(15));
        t.setDayTargetMinute(25);
        t.setIsPastDue(false);
        t.setStudyFinish(false);
        t.setOpenAuto(false);
        t.setRemindTime(null);
        getCurriculumDao().save(t);
    }

    public boolean existCurriculumName(String key) {
        List<Curriculum> list = getCurriculumDao().queryBuilder()
                .where(CurriculumDao.Properties.Title.like(key))
                .where(CurriculumDao.Properties.Status.eq(AppStatus.Status.NORMAL))
                .list();
        return list != null && list.size() > 0;
    }

    public void delCurriculum(Long id) {
        if (id == null) {
            return;
        }
        Curriculum t = getCurriculumDao().load(id);
        if (t == null) {
            return;
        }

        // 清空学习事件
        List<Event> events = findCurriculumEvent(id);
        for (Event e : events) {
            // 删除关联的任务
            ServiceFactory.getInstance().getEventService().delEventTask(e);
            // 删除事件
            getEventDao().delete(e);
        }

        // 课程
        getCurriculumDao().delete(t);
    }

    public void delCurriculumEvent(Long id) {
        Event e = getEventDao().load(id);
        if (e != null) {
            // 删除关联的任务
            ServiceFactory.getInstance().getEventService().delEventTask(e);

            // 删除事件
            getEventDao().deleteByKey(id);
        }
    }

    public Curriculum saveCurriculum(Curriculum t) {
        getCurriculumDao().save(t);

        // 自动续学类事务需要特殊标识
        List<Event> data = findCurriculumEvent(t.getId());
        for (Event e : data) {
            e.setAutoContinue(t.getOpenAuto());
            getEventDao().save(e);
        }

        return t;
    }

    public void doAudoContinue(Event nowEvent) {
        // 非自动续学类事件
        if (!nowEvent.getAutoContinue() || nowEvent.getEventType() != AppStatus.EventType.STUDY || !nowEvent.getFinish()) {
            return;
        }

        Curriculum curriculum = getCurriculumDao().load(nowEvent.getSourceId());
        if (curriculum == null) {
            return;
        }

        List<Event> data = findCurriculumEvent(nowEvent.getSourceId());

        Event waitEvent = null;
        for (Event e : data) {
            if (e.getJoinSchedule() && !e.getFinish()) {
                waitEvent = e;
            }
        }

        // 有已排期未完成的事件,不安排新任务
        if (waitEvent != null) {
            return;
        }


        Event nextEvent = null;
        for (Event e : data) {
            if (!e.getJoinSchedule() && !e.getFinish()) {
                nextEvent = e;
                break;
            }
        }

        if (nextEvent != null) {
            // 排期时间为当前事件的完成时间的下一天
            Date scheduDt = DateUtils.moveDay(nowEvent.getFinishDt(), 1);
            ServiceFactory.getInstance().getEventService().doJoinScheduleAndCreateTask(nextEvent.getId(), scheduDt);
        }

    }

    public void multiInsert(Long id, String content) {
        if (id == null) {
            return;
        }
        Curriculum t = getCurriculumDao().load(id);
        if (t == null) {
            return;
        }

        String[] arr = content.split("#");
        for (String s : arr) {
            if (!TextUtils.isEmpty(s)) {
                Event e = getDefaultEvent(id);
                e.setTitle(s.trim());

                // 自动续学,所属事务需要特殊标记(标记了自动续学的未排期事务不在事件排期列表中展示)
                if (t.getOpenAuto()) {
                    e.setAutoContinue(true);
                }

                getEventDao().save(e);
            }
        }
    }
}
